package net.lesscoding.protocol;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import net.lesscoding.common.Const;

/**
 * @author eleven
 * @date 2024/10/30 17:05
 * @apiNote
 */
@Slf4j
public class HttpTest {
    public static void main(String[] args) {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap()
                    .group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel channel) throws Exception {
                            channel.pipeline()
                                    .addLast(new LoggingHandler(LogLevel.DEBUG))
                                    .addLast(new HttpServerCodec())
                                    .addLast(new SimpleChannelInboundHandler<HttpRequest>() {
                                        @Override
                                        protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpRequest httpRequest) throws Exception {
                                            // 获取请求
                                            log.debug("响应URL： {}", httpRequest.uri());
                                            // 返回响应数据
                                            DefaultFullHttpResponse response = new DefaultFullHttpResponse(
                                                    httpRequest.protocolVersion(),
                                                    HttpResponseStatus.OK);
                                            // 添加响应的长度，防止 浏览器 一直转圈等待响应结束
                                            //String content = StrUtil.format("<h1>{}Hello,World!</h1>", RandomUtil.randomInt());
                                            String content = "{\"code\":1000,\"msg\":\"success\",\"data\":{\"name\":\"eleven\"}}";
                                            byte[] bytes = content.getBytes();
                                            response.headers().set("Content-Type", "application/json;charset=utf-8");
                                            response.headers().set("Content-Length", bytes.length);
                                            response.content().writeBytes(bytes);
                                            channelHandlerContext.writeAndFlush(response);
                                        }
                                    })
                                    /**
                                     *  这里可以用使用 HttpObjectAggregator 来聚合请求体 ，
                                     *  addLast(new HttpObjectAggregator(65536))
                                     *  但是这里需要注意， HttpObjectAggregator 会将请求体聚合为一个 ByteBuf ，
                                     *  所以需要注意， HttpObjectAggregator 的聚合大小，
                                     *   如果请求体过大，会导致内存溢出，
                                     *  或者不使用ChannelInboundHandlerAdapter 而是使用 上边的SimpleChannelInboundHandler 来处理请求体，
                                     *  .addLast(new SimpleChannelInboundHandler<HttpRequest>(){})
                                     *  这样可以让这个处理器只关注后边泛型的消息，过滤掉其他消息
                                     */
                                   /* .addLast(new ChannelInboundHandlerAdapter() {

                                        @Override
                                        public void channelRead(io.netty.channel.ChannelHandlerContext ctx, Object msg) throws Exception {
                                            log.debug("msg Class : {}", msg.getClass());
                                            // 请求行
                                            if (msg instanceof HttpRequest) {

                                            }
                                            // 请求体
                                            if (msg instanceof HttpContent) {

                                            }
                                            super.channelRead(ctx, msg);
                                        }
                                    })*/
                            ;
                        }
                    });
            ChannelFuture future = serverBootstrap.bind(Const.PORT)
                    .sync();
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
